Skip to content

feat: support PROVES Flight Control Board v5e (SX1262 radio)#18

Open
Mikefly123 wants to merge 5 commits into
mainfrom
feat/v5e-board-support
Open

feat: support PROVES Flight Control Board v5e (SX1262 radio)#18
Mikefly123 wants to merge 5 commits into
mainfrom
feat/v5e-board-support

Conversation

@Mikefly123

@Mikefly123 Mikefly123 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a board port so the GRC firmware runs on the PROVES Flight Control Board v5e in addition to the ground_radio_controller and v5 boards.

  • New board boards/proves/proves_flight_control_board_v5e/ — mirrors the v5 port (upstream Pico 2 base + project hardware dtsi with dual CDC ACM, fstab, ramdisk). The only substantive difference is the radio: the v5e carries an SX1262-based E22-400M30S module instead of the v5's SX1276. Wiring follows the v5e board definition in proves-core-reference: reset P6, busy P13, dio1 P14, TX/RX antenna-switch enables P21/P22, DIO3-controlled 1.8V TCXO with 10ms startup delay, rx-boosted. SPI1 pins are identical to v5.
  • prj.conf no longer hard-sets CONFIG_LORA_SX127X. Both SX12xx drivers are default y gated on their devicetree compatible, so the board DT selects the driver. Hard-setting either is a fatal unmet-dependency Kconfig warning for boards carrying the other radio.
  • No app changes: Main.cpp binds the radio via DT_NODELABEL(lora0), which the v5e port defines.
  • README/settings.ini: v5e documented as a BOARD= alternative; ground_radio_controller remains the default.

Testing

  • Built for proves_flight_control_board_v5e/rp2350a/m33; verified CONFIG_LORA_SX126X=y and the full sx1262 node in the merged devicetree.
  • Flashed a bench v5e (UF2 via BOOTSEL) — all 6 one-board main tests pass, including SET_FREQ at 437.4 MHz, which performs a live lora_config() on the SX1262 and would return EXECUTION_ERROR on failure.
  • Regression: rebuilt for ground_radio_controller — builds green with CONFIG_LORA_SX127X=y still selected from its devicetree.

Notes

  • Stock LoRaConfig::TX_POWER = 23 exceeds the SX1262 driver's +22 dBm limit; worth revisiting before running a v5e at full power (not changed here).
  • The two-board (bft2) flow flashes one ELF to both boards, so mixed GRC↔v5e RF link testing needs a follow-up workflow change.

🤖 Generated with Claude Code

Quick builds for manual testing

For manual testing convenience, the branch v5e-portable-builds combines this PR with the portable-builds tooling. Check it out and run make build for a self-bootstrapping build (uv, venv, west workspace, and Zephyr SDK are set up automatically) — no manual environment setup needed. Switch boards by toggling BOARD= in settings.ini, then make generate followed by make build. Both ground_radio_controller and proves_flight_control_board_v5e targets build green on that branch.

Add a v5e board port mirroring the existing v5 port (upstream Pico 2
base + project hardware dtsi) with the v5e's SX1262-based E22-400M30S
LoRa module wiring taken from proves-core-reference: busy P13, dio1
P14, TX/RX antenna-switch enables P21/P22, DIO3-controlled 1.8V TCXO
(10ms startup), rx-boosted. SPI1 wiring is unchanged from v5.

Stop hard-setting CONFIG_LORA_SX127X in prj.conf: both SX12xx drivers
default on when their devicetree compatible is present, so the board
DT now selects the driver. Hard-setting either one is a fatal unmet-
dependency Kconfig warning for boards carrying the other radio.

No app changes needed: Main.cpp binds the radio via DT_NODELABEL(lora0),
which the v5e port defines.

HWIL-verified on a v5e: all 6 one-board main tests pass, including
SET_FREQ which performs a live lora_config() on the SX1262.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for the PROVES Flight Control Board v5e with RP2350A M33 hardware.
    • Added SX1262-based LoRa radio support with automatic driver selection.
    • Added board support for dual USB serial interfaces, SPI, filesystem storage, and RAM disk functionality.
  • Bug Fixes

    • Improved SX1262 wake-up handling to prevent intermittent frequency-setting failures.
  • Documentation

    • Added setup, build, board-switching, and required patch application instructions for the v5e board.

Walkthrough

Adds a PROVES v5e flight controller target with RP2350A/M33 board definitions, SX1262 radio wiring, devicetree-selected LoRa drivers, updated LoRa constants, and documentation for board switching and the required SX126x wake-up patch.

Changes

v5e board support

Layer / File(s) Summary
Board identity and build configuration
boards/proves/proves_flight_control_board_v5e/*
Defines the v5e board symbol, metadata, RP2350A/M33 resources, supported peripherals, and default HEX/UF2 build settings.
Devicetree hardware wiring
boards/proves/proves_flight_control_board_v5e/*.dts*
Includes upstream RP2350A/M33 definitions and configures CDC ACM UARTs, SPI1, the SX1262 radio, console mapping, filesystem, and RAM disk.
Driver and runtime configuration
prj.conf, FprimeZephyrReference/project/config/LoRaCfg.hpp, settings.ini
Uses devicetree-based LoRa driver selection, updates bandwidth and payload header declarations, and comments out board selections in settings.
Wake-up patch and board instructions
patches/*, README.md
Adds the SX126x BUSY polling delay patch and documents applying it, switching to v5e, generating force files, and flashing the board.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested reviewers: jrpear, ineskhou

Poem

A v5e board joins the flight,
Its SX1262 wired just right.
The driver follows the tree,
A wake-up patch sets signals free.
Hop, generate, build, and soar! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding PROVES Flight Control Board v5e support with an SX1262 radio.
Description check ✅ Passed The description directly matches the changeset, covering the new board port, driver selection, docs, and testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/v5e-board-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The Zephyr SX126x driver polls BUSY immediately after the wake-up SPI
transaction, racing the chip's ~340us warm start. When the poll samples
BUSY before the chip asserts it, the next SPI command is clocked into a
device still starting up and silently ignored. The driver sleeps the
radio after every operation and the first command after wake is always
SetRfFrequency, so SET_FREQ intermittently failed to retune the SX1262
(7 of 18 register writes dropped in release-build measurements on a
v5e; debug builds mask the race via logging delay).

Carry the one-line fix (wait out the startup window before polling) as
a patch file since the zephyr submodule tracks upstream. Verified on
hardware by reading back the RF frequency PLL registers (0x088B) after
each write: 0 drops in 35 retunes with the fix, and the two-board RF
suite passes in both directions on a mixed GRC(SX1276) + v5e(SX1262)
pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jrpear jrpear mentioned this pull request Jul 7, 2026
+ * next command is clocked into a device still starting up and is
+ * silently ignored. Wait out the startup window before polling.
+ */
+ k_busy_wait(500);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused about this patch. We're not sleeping the radio as far as I know. And in any case the datasheet doesn't say "wait after wake" to send commands, it says "wait after sleep".

It is possible the delay just changed the timing of things so as to disguise a race condition causing the intermittent SET_FREQ failures the new README mentions.

Mikefly123 and others added 3 commits July 8, 2026 14:20
…n RX

Commit 37b2808 ("Remove unused LoRa payload header", 2026-04-20) zeroed
the GRC LoRa payload header to HEADER[0]={}, but the flight firmware's
LoRa::receive() always strips sizeof(LoRaConfig::HEADER) bytes from the
front of every received LoRa packet, and the flight's LoRaCfg.hpp still
defines HEADER[]={0,0,0,0} (4 bytes).

Effect: every GRC→LoRa→flight uplink packet arrived with its first 4
bytes removed.  Those bytes are the CCSDS TC frame flagsAndScId field
(expected value 0x2044).  CcsdsTcFrameDetector returned NO_FRAME_DETECTED
on every packet; FrameAccumulator's byte-by-byte sliding search never
recovered because 0x2044 does not appear anywhere in the TC payload.
Commands were silently discarded.  The only visible symptom was that
lora.m_bytes_received on the flight board kept rising (the LoRa radio
layer counts bytes before the frame detector runs) while no command
events ever appeared.

Fix: restore HEADER[]={0,0,0,0} so the GRC prepends the same 4-byte
prefix that the flight expects to strip, keeping the TC frame intact.

Verified 2026-06-22 on bench: GET_SEQ_NUM returned EmitSequenceNumber
in ~1 s; CMD_NO_OP returned NoOpReceived + OpCodeCompleted in 1.18 s
over the full GDS→authenticate-space-data-link→GRC→LoRa→flight path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions

Both were non-const namespace-scope variables defined in a header included
by multiple translation units, creating an ODR violation hazard.  Neither
is ever modified after initialization: HEADER is only read via sizeof() and
memcpy() (which takes const void*), and BANDWIDTH is not referenced via
LoRaConfig:: at all (the LoRa component reads bandwidth through F´ params).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ore-lora-header

fix(LoRaCfg): restore 4-byte LoRa payload header on v5e branch

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@patches/README.md`:
- Around line 24-27: Label the shell command code block containing the git apply
command with the bash language identifier by changing its opening fence to
```bash.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f57d017d-ae08-4b7b-a0d4-08dbd2ddf734

📥 Commits

Reviewing files that changed from the base of the PR and between 55eef15 and fcfff6a.

📒 Files selected for processing (4)
  • FprimeZephyrReference/project/config/LoRaCfg.hpp
  • README.md
  • patches/README.md
  • patches/zephyr-sx126x-wakeup-busy-delay.patch

Comment thread patches/README.md
Comment on lines +24 to +27
```
cd lib/zephyr-workspace/zephyr
git apply ../../../patches/zephyr-sx126x-wakeup-busy-delay.patch
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Label the shell command block.

Line 24 should use ```bash so Markdown linting can identify the command language.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 24-24: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@patches/README.md` around lines 24 - 27, Label the shell command code block
containing the git apply command with the bash language identifier by changing
its opening fence to ```bash.

Source: Linters/SAST tools

@jrpear

jrpear commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

I'm happy to add the new devicetree files but reluctant to accept the Zephyr patch until I understand why we need it

@jrpear

jrpear commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Be advised I have seen the integration tests be a bit flaky, so it's possible that your AI just saw a flaking test and tried random stuff until you got lucky with a successful test.

@jrpear

jrpear commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

See #6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants